home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / lists / mint / l_0799 / 662 < prev    next >
Encoding:
Internet Message Format  |  1994-08-27  |  7.0 KB

  1. From: Andreas Schwab <schwab@lamothe.informatik.uni-dortmund.de>
  2. Date: Tue, 23 Nov 93 11:09:20 +0100
  3. Message-Id: <9311231009.AA01151@lamothe.informatik.uni-dortmund.de>
  4. To: mint@atari.archive.umich.edu
  5. Subject: MiNT 1.09 extension: /dev/fd/*
  6.  
  7. This patch implements the /dev/fd directory, denoting the open file
  8. descriptors of the current process. This is a generalisation of
  9. /dev/std{in,out,err}.
  10.  
  11. I have implemented this for Bash-1.13, which uses it for process
  12. substitution; unfortunately this doesn't work because of the blocking
  13. fork() :-(. Anyway, i think this is a nice thing.
  14.  
  15. --- orig/biosfs.c    Tue Aug 17 21:23:18 1993
  16. +++ biosfs.c    Sat Nov 20 19:50:40 1993
  17. @@ -136,6 +136,7 @@
  18.      {"stdin", &fakedev, 0, 0, 0, 0},  /* handle 0 (stdin) */
  19.      {"stdout", &fakedev, 1, 0, 0, 0}, /* handle 1 (stdout) */
  20.      {"stderr", &fakedev, 2, 0, 0, 0}, /* handle 2 (stderr) */
  21. +    {"fd", &fakedev, S_IFDIR, 0, 0, 0}, /* file descriptor directory */
  22.  
  23.  /* other miscellaneous devices */
  24.      {"mouse", &mouse_device, 0, 0, 0, 0},
  25. @@ -157,6 +158,11 @@
  26.      {"", 0, 0, 0, 0, 0}
  27.  };
  28.  
  29. +/* Does the fcookie fc refer to the \dev\fd directory? */
  30. +#define IS_FD_DIR(fc) ((fc)->aux == S_IFDIR)
  31. +/* Does the fcookie fc refer to a file in the \dev\fd directory? */
  32. +#define IS_FD_ENTRY(fc) ((fc)->index > 0 && (fc)->index <= MAX_OPEN-MIN_HANDLE)
  33. +
  34.  struct bios_file *broot, *bdevlast;
  35.  
  36.  /* a file pointer for BIOS device 1, provided only for insurance
  37. @@ -234,9 +240,41 @@
  38.      struct bios_file *b;
  39.  
  40.      if (dir->index != 0) {
  41. +      /* Check for \dev\fd directory */
  42. +      if (!IS_FD_DIR (dir))
  43. +        {
  44.          DEBUG(("bios_lookup: bad directory"));
  45.          return EPTHNF;
  46. +        }
  47. +      if (!*name || (name[0] == '.' && name[1] == 0))
  48. +        {
  49. +          *fc = *dir;
  50. +          return 0;
  51. +        }
  52. +      if (!strcmp (name, ".."))
  53. +        {
  54. +          /* Root directory */
  55. +          fc->fs = &bios_filesys;
  56. +          fc->dev = dir->dev;
  57. +          fc->index = 0L;
  58. +          return 0;
  59. +        }
  60. +      if (isdigit (*name) || *name == '-')
  61. +        {
  62. +          int fd = (int) atol (name);
  63. +          if (fd >= MIN_HANDLE && fd < MAX_OPEN)
  64. +        {
  65. +          fc->fs = &bios_filesys;
  66. +          fc->dev = dir->dev;
  67. +          fc->aux = fd;
  68. +          fc->index = fd - MIN_HANDLE + 1;
  69. +          return 0;
  70. +        }
  71. +        }
  72. +      DEBUG (("bios_lookup: name(%s) not found", name));
  73. +      return EFILNF;
  74.      }
  75. +
  76.  /* special case: an empty name in a directory means that directory */
  77.  /* so does "." */
  78.      if (!*name || (name[0] == '.' && name[1] == 0)) {
  79. @@ -270,6 +308,7 @@
  80.  {
  81.      FILEPTR *f;
  82.      struct bios_file *b = (struct bios_file *)fc->index;
  83. +    long r;
  84.  
  85.      xattr->index = fc->index;
  86.      xattr->dev = fc->dev;
  87. @@ -279,18 +318,42 @@
  88.      xattr->blksize = 1;
  89.      xattr->mtime = xattr->atime = xattr->ctime = timestamp;
  90.      xattr->mdate = xattr->adate = xattr->cdate = datestamp;
  91. -    if (fc->index == 0) {        /* root directory? */
  92. +    if (fc->index == 0 || IS_FD_DIR (fc)) { /* root or fd directory? */
  93.          xattr->mode = S_IFDIR | DEFAULT_DIRMODE;
  94.          xattr->attr = FA_DIR;
  95. +    }
  96. +    else if (IS_FD_ENTRY (fc)) {
  97. +        /* u:\dev\fd\... */
  98. +        f = curproc->handle[(int) fc->aux];
  99. +        if (f)
  100. +          {
  101. +        r = (*f->fc.fs->getxattr) (&f->fc, xattr);
  102. +        if (r < 0)
  103. +          return r;
  104. +#if 0
  105. +        /* Not sure if needed. Try without it for now */
  106. +        xattr->index = fc->index;
  107. +        xattr->dev = fc->dev;
  108. +#endif
  109. +          }
  110. +        else
  111. +          {
  112. +        xattr->mode = S_IFCHR | DEFAULT_MODE;
  113. +        xattr->attr = 0;
  114. +          }
  115.      } else if (b->device == 0) {    /* symbolic link? */
  116.          xattr->mode = S_IFLNK | DEFAULT_DIRMODE;
  117.      } else if (b->device == &fakedev &&
  118.          (f = curproc->handle[b->private]) != 0)
  119.      {
  120.          /* u:\dev\stdin, u:\dev\stdout, etc. */
  121. -        (*f->fc.fs->getxattr) (&f->fc, xattr);
  122. +        r = (*f->fc.fs->getxattr) (&f->fc, xattr);
  123. +        if (r < 0)
  124. +          return r;
  125. +#if 0
  126.          xattr->index = fc->index;
  127.          xattr->dev = fc->dev;
  128. +#endif
  129.      } else {
  130.          xattr->mode = S_IFCHR | DEFAULT_MODE;
  131.          xattr->attr = 0;
  132. @@ -357,7 +420,10 @@
  133.  {
  134.      struct bios_file *b, **lastb;
  135.  
  136. -    UNUSED(dir);
  137. +    /* Don't allow removal in the fd directory */
  138. +    if (IS_FD_DIR (dir))
  139. +      return EACCDN;
  140. +
  141.      lastb = &broot;
  142.      for (b = broot; b; b = *(lastb = &b->next)) {
  143.          if (!stricmp(b->name, name)) break;
  144. @@ -382,12 +448,22 @@
  145.      fcookie *root, *dir; char *pathname;
  146.      int size;
  147.  {
  148. -    char *foo = ((struct bios_file *)dir->index)->name;
  149. +    char *foo;
  150.  
  151. -    UNUSED(root);
  152. -    if (dir->index == 0 && size > 0)
  153. -        *pathname = 0;
  154. -    else if (strlen(foo) < size)
  155. +    if (size == 0)
  156. +      return ERANGE;
  157. +    if (root->index == dir->index)
  158. +      {
  159. +        *pathname = 0;
  160. +        return 0;
  161. +      }
  162. +    /* DIR must point to the fd directory */
  163. +    if (!IS_FD_DIR (dir))
  164. +      return EINTRN;
  165. +    *pathname++ = '\\';
  166. +    size--;
  167. +    foo = ((struct bios_file *)dir->index)->name;
  168. +    if (strlen(foo) < size)
  169.          strcpy(pathname, foo);
  170.      else
  171.          return ERANGE;
  172. @@ -401,18 +477,22 @@
  173.      fcookie *newdir;
  174.      const char *newname;
  175.  {
  176. -    struct bios_file *b;
  177. -
  178. -    UNUSED(olddir); UNUSED(newdir);
  179. +    struct bios_file *b, *be = 0;
  180.  
  181. -/* BUG: we should check to see if "newname" already exists */
  182. +    if (IS_FD_DIR (olddir) || IS_FD_DIR (newdir))
  183. +      return EACCDN;
  184.  
  185.      for (b = broot; b; b = b->next) {
  186. -        if (!stricmp(b->name, oldname)) {
  187. -            strncpy(b->name, newname, BNAME_MAX);
  188. -            return 0;
  189. -        }
  190. -    }
  191. +        if (!stricmp(b->name, oldname))
  192. +          be = b;
  193. +        else if (!stricmp (b->name, newname))
  194. +          return EACCDN;
  195. +    }
  196. +    if (be)
  197. +      {
  198. +        strncpy(be->name, newname, BNAME_MAX);
  199. +        return 0;
  200. +      }
  201.      return EFILNF;
  202.  }
  203.  
  204. @@ -423,7 +503,7 @@
  205.  {
  206.      UNUSED(flags);
  207.  
  208. -    if (dirh->fc.index != 0) {
  209. +    if (dirh->fc.index != 0 && !IS_FD_DIR (&dirh->fc)) {
  210.          DEBUG(("bios_opendir: bad directory"));
  211.          return EPTHNF;
  212.      }
  213. @@ -440,6 +520,31 @@
  214.      struct bios_file *b;
  215.      int giveindex = dirh->flags == 0;
  216.      int i;
  217. +    char buf[5];
  218. +
  219. +    if (IS_FD_DIR (&dirh->fc))
  220. +      {
  221. +        i = dirh->index++;
  222. +        if (i + MIN_HANDLE >= MAX_OPEN)
  223. +          return ENMFIL;
  224. +        fc->fs = &bios_filesys;
  225. +        fc->index = i + 1;
  226. +        fc->aux = i + MIN_HANDLE;
  227. +        fc->dev = dirh->fc.dev;
  228. +        if (giveindex)
  229. +          {
  230. +        namelen -= (int) sizeof (long);
  231. +        if (namelen <= 0)
  232. +          return ERANGE;
  233. +        *(long *) name = (long) i + 1;
  234. +        name += sizeof (long);
  235. +          }
  236. +        ksprintf (buf, "%d", i + MIN_HANDLE);
  237. +        strncpy (name, buf, namelen-1);
  238. +        if (strlen (buf) >= namelen)
  239. +          return ENAMETOOLONG;
  240. +        return 0;
  241. +      }
  242.  
  243.      b = broot;
  244.      i = dirh->index++;
  245. @@ -551,7 +656,9 @@
  246.  {
  247.      struct bios_file *b;
  248.  
  249. -    UNUSED(dir);
  250. +    if (IS_FD_DIR (dir))
  251. +      return EINVFN;
  252. +
  253.      if ((unsigned)cmd == DEV_INSTALL) {
  254.          struct dev_descr *d = (struct dev_descr *)arg;
  255.  
  256. @@ -609,6 +716,9 @@
  257.      long r;
  258.      fcookie fc;
  259.  
  260. +    if (IS_FD_DIR (dir))
  261. +      return EACCDN;
  262. +
  263.      r = bios_lookup(dir, name, &fc);
  264.      if (r == 0) return EACCDN;    /* file already exists */
  265.      if (r != EFILNF) return r;    /* some other error */
  266. @@ -640,6 +750,8 @@
  267.  {
  268.      struct bios_file *b = (struct bios_file *)fc->index;
  269.  
  270. +    if (IS_FD_DIR (fc) || IS_FD_ENTRY (fc))
  271. +      return EINVFN;
  272.      if (!b) return EINVFN;
  273.      if (b->device) return EINVFN;
  274.  
  275. @@ -758,6 +870,13 @@
  276.  {
  277.      struct bios_file *b;
  278.  
  279. +    /* Check for \dev\fd\... */
  280. +    if (IS_FD_ENTRY (fc))
  281. +      {
  282. +        *devsp = (int) fc->aux;
  283. +        return &fakedev;
  284. +      }
  285. +
  286.      b = (struct bios_file *)fc->index;
  287.  
  288.      if (b->device && b->device != &fakedev)
  289.